home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / asmutil / afloat.zip / FDIVIDE.ASM < prev    next >
Assembly Source File  |  1988-03-15  |  3KB  |  151 lines

  1.         PAGE ,132
  2. ;----------------------------------------------------------
  3. ; FDIVIDE -- version for use with assembly language programs
  4. ;
  5. ; Copyright Bob Kline 1988
  6. ;
  7. ; Purpose:
  8. ;       Divide two single-precision floating-point numbers.
  9. ;
  10. ; Input:
  11. ;       DX:AX contain dividend in single-precision IEEE
  12. ;       format; CX:BX contain divisor, same format.
  13. ;
  14. ; Output:
  15. ;       Quotient (IEEE) single-precision real in DX:AX.
  16. ;
  17. ; Other registers affected:
  18. ;       BX, CX, DI, SI, BP
  19. ;
  20. ; Procedures:
  21. ;       None.
  22. ;
  23. ; Comments:
  24. ;       Sets external variable _errno to ERANGE if over-
  25. ;       flow occurs, or EDOM if an attempt is made to divide
  26. ;       by zero.  If a calling routine will be testing
  27. ;       _errno, it must first reset the variable to zero
  28. ;       to be sure that an error code is not left over
  29. ;       from some previous call.
  30. ;----------------------------------------------------------
  31.  
  32.         .MODEL  SMALL
  33.  
  34.         PUBLIC  FDIVIDE
  35.         EXTRN   _errno:WORD
  36.  
  37. EDOM            EQU     33
  38. ERANGE        EQU    34
  39.  
  40.     .CODE
  41.  
  42. FDIVIDE PROC
  43.  
  44. ; check for division by zero
  45.         OR      CX,CX
  46.         JNZ     OK
  47.         OR      BX,BX
  48.         JNZ     OK
  49.         MOV     _errno,EDOM
  50.         MOV     AX,0FFFFh
  51.         MOV     DX,0FF7Fh
  52.         RET
  53.  
  54. ; get sign of result and save it
  55. OK:     MOV     SI,DX
  56.     XOR    DX,CX
  57.     AND    DX,8000h
  58.     PUSH    DX
  59.     MOV    DX,SI
  60.  
  61. ; subtract exponents, save result
  62.         MOV     BP,CX
  63.     MOV    DI,DX
  64.     SHL    DX,1
  65.     SHL    CX,1
  66.     XCHG    DH,DL
  67.     XCHG    CH,CL
  68.     XOR    DH,DH
  69.     XOR    CH,CH
  70.     SUB    CX,127
  71.     SUB    DX,127
  72.         SUB     DX,CX
  73.         PUSH    DX
  74.         MOV     DX,DI
  75.  
  76. ; unpack mantissas -- note that high word of divisor
  77. ;   is now in BP so that we can use CX for shift count
  78.     AND    DX,7Fh
  79.         AND     BP,7Fh
  80.     OR    DX,80h
  81.         OR      BP,80h
  82.  
  83. ; multiply DX:AX by BP:BX
  84.         MOV     CX,26
  85.         XOR     SI,SI
  86.         XOR     DI,DI
  87.         JMP     SHORT START
  88. SHIFTS: SHL     SI,1
  89.         RCL     DI,1
  90.         RCL     AX,1
  91.         RCL     DX,1
  92. START:  CMP     DX,BP
  93.         JB      NOTYET
  94.         JA      YES
  95.         CMP     AX,BX
  96.         JB      NOTYET
  97. YES:    SUB     AX,BX
  98.         SBB     DX,BP
  99.         INC     SI
  100. NOTYET: LOOP    SHIFTS
  101.         MOV     DX,DI
  102.         MOV     AX,SI
  103.  
  104. ; we divided either 1 or 2 places further than what we
  105. ;   we will be able to use in the long run -- at least
  106. ;   one more than necessary so that we can round the
  107. ;   result -- if we wound up with 2 more places than
  108. ;   needed shift right and increment the exponent, which
  109. ;   we get back from the stack
  110.         POP     BX
  111.         TEST    DX,200h
  112.         JZ      NO_EXTRA
  113.         SHR     DX,1
  114.         RCR     AX,1
  115.         INC     BX
  116.  
  117. ; shift out the extra place, noting first the discarded
  118. ;   bit for rounding
  119. NO_EXTRA:
  120.         MOV     CX,AX
  121.         AND     CX,1
  122.         SHR     DX,1
  123.         RCR     AX,1
  124.         ADD     AX,CX
  125.         ADC     DX,0
  126.  
  127. ; remove the topmost bit -- it's understood
  128.         AND     DX,7Fh
  129.  
  130. ; restore exponent bias and test for range error
  131.         ADD     BX,126
  132.         TEST    BX,0FF00h
  133.         JZ      INRANGE
  134.         MOV     _errno,ERANGE
  135.         XOR     BH,BH
  136.  
  137. ; fold the exponent back into DX:AX
  138. INRANGE:
  139.         XCHG    BH,BL
  140.         SHR     BX,1
  141.         OR      DX,BX
  142.  
  143. ; get back the sign bit
  144.         POP     CX
  145.         OR      DX,CX
  146.         RET
  147.  
  148. FDIVIDE ENDP
  149.  
  150.     END
  151.